import myconfig  from "@/config/index";
import store from '@/config/store.js';
import md5js from "@/config/md5.js";
import { http } from '@/utils/luch-request/index.js'
const apiObj = {
	checkUserInfo(type,userInfo){
		type = type?type:'get';
		userInfo = userInfo?userInfo:{};
		switch(type)
		{
			case 'set':
				uni.setStorageSync('cache_userInfo',userInfo);
				break;
			case 'get':
				if(this.checkLogin() == false)
				{
					return {};
				}
				var userInfo = uni.getStorageSync('cache_userInfo');
				if(!userInfo || userInfo == '')
				{
					return {};
				}
				return userInfo;
				break;
			case 'del':
				uni.removeStorageSync('cache_userInfo');
				break
		}
	},
	checkLogin(showForceLogin)
	{
		var token = this.jwtToken();
		if(!token)
		{
			this.checkUserInfo('del'); //清除本地缓存的用户信息
			store.commit('loginStatus', false);
			if(showForceLogin == true)
			{
				store.commit('showForceLogin', true);
			}
			return false;
		}else{
			store.commit('loginStatus', true);
			return true;
		}
	},
	jwtToken:function(type,tokenObj){
		type = type?type:'get';
		tokenObj = tokenObj?tokenObj:{};
		switch(type)
		{
			case 'set':
				uni.setStorageSync('jwt_token',tokenObj.jwt_token);
				uni.setStorageSync('jwt_token_exp_time',tokenObj.exp_time);
				this.checkLogin();//更改登录状态
				break;
			case 'get':
				var jwt_token = uni.getStorageSync('jwt_token');
				if(!jwt_token || jwt_token == '')
				{
					return '';
				}
				var jwt_token_exp_time = uni.getStorageSync('jwt_token_exp_time');
				jwt_token_exp_time = jwt_token_exp_time?parseInt(jwt_token_exp_time):0;
				if(jwt_token_exp_time < this.getTime())
				{
					this.jwtToken('del'); 
					return '';
				}
				return jwt_token;
				break;
			case 'del':
				uni.removeStorageSync('jwt_token');
				uni.removeStorageSync('jwt_token_exp_time');
				this.checkLogin();//更改登录状态
				break
		}
	},
	//获取当前时间
	getTime:function(){
		var time = Date.now();
		return parseInt(time/1000);
	},
	//时间转时间戳
	timeToNumber(time){
		var that = this;
		if(!time || time == '')
		{
			return 0;
		}
		var intTime = 0;
		try{
			intTime = new Date(time.replace(/-/g, '/')).getTime() / 1000;
		}catch(e){
			that.msg('时间转换错误')
		}
		return intTime;
	},
	getDateRange:function(dateNow,intervalDays,resLength,bolPastTime){
		dateNow = dateNow?dateNow:new Date();
		resLength = resLength?parseFloat(resLength):3;
		let oneDayTime = 24 * 60 * 60 * 1000;
		let list = [];
		let lastDay;

		if(bolPastTime == true){
			lastDay = new Date(dateNow.getTime() - intervalDays * oneDayTime);
			list.push(this.formateDate(lastDay,resLength));
			list.push(this.formateDate(dateNow,resLength));
		}else{
			lastDay = new Date(dateNow.getTime() + intervalDays * oneDayTime);
			list.push(this.formateDate(dateNow,resLength));
			list.push(this.formateDate(lastDay,resLength));
		}
		return list;
	},
	formateDate:function(time,length){
		let year = time.getFullYear();
		year = year > 9 ? year : '0' + year.toString();
		let month = time.getMonth() + 1;
		month = month > 9 ? month : '0' + month.toString();
		let day = time.getDate();
		day = day > 9 ? day : '0' + day.toString();
		let hour = time.getHours();
		hour = hour > 9 ? hour : '0' + hour.toString()
		let minute = time.getMinutes();
		minute = minute > 9 ? minute : '0' + minute.toString()
		let second = time.getSeconds();
		second = second > 9 ? second : '0' + second.toString()
		switch(length){
			case 1:
				return year;
			case 2:
				return year + '/' + month;
			case 3:
				return year + '-' + month + '-' + day + '';
			case 4:
				return year + '-' + month + '-' + day + ' '+hour;
			case 5:
				return year + '-' + month + '-' + day + ' '+hour+':'+minute;
			case 6:
				return year + '-' + month + '-' + day + ' '+hour+':'+minute+':'+second;
			default:
				return '';
		}
		
	},
	splitStrRN:function(str,checkRepeat,checkTrim=1){
		//checkTrim 是否排除只是空白的内容
		if(!str)
		{
			return {
				status:true,
				list:[]
			};
		}
		//checkRepeat 是否检测重复
		str = str.replace(/\n/g,',');
		str = str.replace('，',',');
		var strArr = str.split(",");
		if(strArr.length < 1)
		{
			return {
				status:true,
				list:[]
			};
		}
		if(checkTrim == 1)
		{
			for(var i=0;i<strArr.length;i++)
			{
				strArr[i] =  strArr[i] && strArr[i].replace(/\n/g,'') && strArr[i].trim(); 
			}
			strArr = strArr.filter(function (s) {
			    return s && s.trim(); 
			})
		}
		var hasRepeat = false;
		if(checkRepeat)
		{
			var newStrArr = [];
			for(var i=0;i<strArr.length;i++) {
				if(newStrArr.indexOf(strArr[i]) > -1)
				{
					this.msg(`填写的内容中"${strArr[i]}"重复`);
					hasRepeat = true;
					break;
				}else{
					newStrArr.push(strArr[i]);
				}
			}
		}
		if(hasRepeat)
		{
			return {
				status:false,
				list:[]
			};
		}
		return {
			status:true,
			list:strArr
		};
	},
	isPhoneNumber:function(mobile){
		if(!mobile){
			return false;
		}
		var reg =/^0?1[1|2|3|4|5|6|7|8|9][0-9]\d{8}$/;
		return reg.test(mobile);
	},
	checkEmail(email){
		if(!email)
		{
			return false;
		}
		var reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
		//调用正则验证test()函数
		var isok= reg.test(email);
		if(!isok) {
			return false;
		}
		return true;
	},
	checkCard:function(card)
	{
		if(!card)
		{
			return false;
		}
	    card=card.toLowerCase();
	    var vcity={ 11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"};
	    var arrint = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
	    var arrch = new Array('1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2');
	    var reg = /(^\d{15}$)|(^\d{17}(\d|x)$)/;
	    if(!reg.test(card))return false;
	    if(vcity[card.substr(0,2)] == undefined)return false;
	    var len=card.length;
	    if(len==15)
	        reg=/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/;
	    else
	        reg=/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|x)$/;
	    var d,a = card.match(new RegExp(reg));
	    if(!a)return false;
	    if (len==15){
	        d = new Date("19"+a[2]+"/"+a[3]+"/"+a[4]);
	    }else{
	        d = new Date(a[2]+"/"+a[3]+"/"+a[4]);
	    }
	    if (!(d.getFullYear()==a[2]&&(d.getMonth()+1)==a[3]&&d.getDate()==a[4]))return false;
	    if(len=18)
	    {
	        len=0;
	        for(var i=0;i<17;i++)len += card.substr(i, 1) * arrint[i];
	        return arrch[len % 11] == card.substr(17, 1);
	    }
	    return true;
	},
	checkChinese:function(item){
        // console.log(item)     
		var re = /[^\u4e00-\u9fa5]/;
		if (re.test(item)) {
	        return false;
	    } 
		return true;
	},
	checkEnglish:function(item){
	    // console.log(item)     
		var re = /[^\a-\z\A-\Z]/g;
		if (re.test(item)) {
	        return false;
	    } 
		return true;
	},
	checkEnNumber:function(item){
	    // console.log(item)     
		var re = /[^\a-z\A-Z\0-9]/g;
		if (re.test(item)) {
	        return false;
	    } 
		return true;
	},
	makePhone:function(phone){
		if(!this.isPhoneNumber(phone)){
			this.msg('不是正确的手机号');
			return false;
		}
		uni.makePhoneCall({
			phoneNumber: phone //仅为示例
		});
	},
	msg:function(title, duration=1000, mask=false, icon='none'){
		title = title?title.toString():'';
		//统一提示方便全局修改
		if(Boolean(title) === false){
			return;
		}
		uni.showToast({
			title,
			duration,
			mask,
			icon
		});
	},
	loadingMsg:function(title,mask=true){
		title = title?title.toString():'';
		//统一提示方便全局修改
		//if(Boolean(title) === false){return;}
		uni.showLoading({title,mask,});
	},
	showModal:function(title,content,callback,params){
		title = title?title.toString():'提示';
		var showCancel = (params && params.hideCancel)?false:true;
		var confirmText = (params && params.confirmText)?params.confirmText:'确定';
		uni.showModal({
		    title: title,
		    content: content,
			showCancel:showCancel,
			confirmText:confirmText,
		    success: function (res) {
		        if (res.confirm) {
		            var returnRes = 'yes';
		        } else if (res.cancel) {
					var returnRes = 'no';
		        }
				if(typeof callback == 'function')
				{
					callback(returnRes,params);
				};
		    }
		});
	},
	urlencode:function(str) {
		str = (str + '').toString();
		return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
		replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
	},
	urldecode:function(zipStr){ 
	  var uzipStr = ''; 
	  for (var i = 0; i < zipStr.length; i += 1) {
	    var chr = zipStr.charAt(i); 
	    if (chr === '+') { 
	      uzipStr += ' ';
	    } else if (chr === '%') { 
	      var asc = zipStr.substring(i + 1, i + 3); 
	      if (parseInt('0x' + asc) > 0x7f) {
	        uzipStr += decodeURI('%' + asc.toString() + zipStr.substring(i+3, i+9).toString()); 
	        i += 8;
	      }else{ 
	        uzipStr += String.fromCharCode(parseInt('0x' + asc)); 
	        i += 2;
	      } 
	    }else{ 
	      uzipStr += chr; 
	    } 
	  } 
	
	  return uzipStr; 
	},
	checkIsHttpUrl:function(url){
		var str = url;
		//判断URL地址的正则表达式为:http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
		//下面的代码中应用了转义字符"\"输出一个字符"/"
		var Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
		var objExp = new RegExp(Expression);
		if(objExp.test(str) == true){
			return true;
		}else{
			return false;
		}
	},
	navigateTo:function(url,url_type){
		var _this = this;
		url_type = url_type?url_type:1; //1站内跳转  2站外跳转
		if(!url)
		{
			_this.msg('缺少跳转链接');return ;
		}
		if(url_type == 1)
		{
			uni.navigateTo({
			    url: url,
				fail(res) {
					//尝试tabbar跳转
					uni.switchTab({
						url: url,
						fail(res) {
							_this.msg('无法跳转页面');
						}
					});
				}
			});
		}else if(url_type == 2){
			if(!_this.checkIsHttpUrl(url)){
				_this.msg('非完整的http链接');
				return false;
			}
			var token = apiObj.jwtToken();
			if(token && url.indexOf('token=') == -1)
			{
				//必须检测到token 而且这个url不带有token
				if(url.indexOf('?')> -1)
				{
					url = url+'&token='+token
				}else{
					url = url+'?token='+token 
				}
			}
			url = _this.urlencode(url);
			uni.navigateTo({
			    url: '/pages/common/show-webview?web_url='+url,
				fail(res) {
					_this.msg('无法跳转链接');
				}
			});
		}
	},
	navbackTo:function(delta){
		var pages = getCurrentPages();
		if(pages.length == 1)
		{
			uni.switchTab({
				url:'/pages/index/index'
			})
			return ;
		}
		delta = delta?delta:1;
		uni.navigateBack({
			delta:delta
		});
	},
	openLocation:function(lat,lng,params)
	{
		var that = this;
		params = params?params:{};
		uni.openLocation({
			latitude: parseFloat(lat),
			longitude: parseFloat(lng), 
			scale:params.scale?params.scale:12,
			address:params.address?params.address:'',
			success: function () {
				//console.log('success');
			},
			fail(e){
				that.msg('显示地图位置失败：'+e.errno)
			}
		});
	},
	chooseLocation:function(callbackFunc){
		uni.authorize({
		    scope: 'scope.userLocation',
		    success(e) {
		        uni.getLocation({
		        	type: 'gcj02', //返回可以用于uni.openLocation的经纬度
		        	success: function (res) {
		        		const latitude = res.latitude;
		        		const longitude = res.longitude;
		        		uni.chooseLocation({
		        			latitude: latitude,
		        			longitude: longitude,
		        			success: function (e) {
								if(typeof callbackFunc == 'function')
								{
									callbackFunc(e)
								}
		        			},
		        		});
		        	},
		        }); 
		    },
			fail(e) {
				uni.showModal({
					title:'请先允许获取地理位置',
					confirmText:'去授权',
					success:function(res){
						if(res.confirm)
						{
							uni.openSetting({})
						}
					},
				})
				 
			}
		})
	},
	getLocation:function(callbackFunc){
		var that = this;
		uni.authorize({
		    scope: 'scope.userLocation',
		    success(e) {
		        uni.getLocation({
		        	type: 'wgs84', //返回可以用于uni.openLocation的经纬度
		        	success: function (res) {
						var lat = res.latitude;
						var lng = res.longitude;
						var postStr = `{"lon":${lng},"lat":${lat},"ver":1}`
						uni.request({
						    url: 'https://api.tianditu.gov.cn/geocoder?postStr='+postStr+'&type=geocode&tk=cbe3448ebe9025ff1a0a7fc6be6846a9', //仅为示例，并非真实接口地址。
						    success: (res) => {
								uni.hideLoading()
								//console.log(res)
								var data = res.data?res.data:{};
								if(data.result && data.result.formatted_address)
								{
									/* uni.showModal({
										content:JSON.stringify(data.result)
									}) */
									if(typeof callbackFunc == 'function')
									{
										callbackFunc({
											lat:lat,
											lng:lng,
											address:data.result.formatted_address
										})
									}
								}else{
									that.msg((res.msg?res.msg:'获取定位失败'));
								}
						    },
							fail(res){
								uni.hideLoading()
								that.msg((res.errMsg?res.errMsg:'获取定位位置异常'));
							}
						});
		        	},
					fail(res){
						uni.hideLoading()
						console.log("定位失败"+JSON.stringify(res))
						that.msg((res.errMsg?res.errMsg:'未获取到当前位置'));
					}
		        }); 
		    },
			fail(e) {
				uni.hideLoading();
				uni.showModal({
					title:'请先允许获取地理位置',
					confirmText:'去授权',
					success:function(res){
						if(res.confirm)
						{
							uni.openSetting({})
						}
					},
				})
				 
			}
		})
	},
	//处理表单数据
	opeDiyFormData(data){
		var data = data?data:[];
		var _this = this;
		if(data.length < 1)
		{
			_this.msg('未设置内容');
		}
		var unsetKey = ['icon','icon_size'];
		var hasErrorText = '';
		//console.log(data)
		for(var i=0;i<data.length;i++)
		{
			unsetKey.forEach(function(item){
				try{
					if(data[i].hasOwnProperty(item))
					{
						delete data[i][item];
					} 
				}catch(e){
					
				}
			})
			let info = data[i];
			var index = i+1;
			//info.value = info.value?info.value.trim():'';
			if(!info.value || info.value == '')
			{
				hasErrorText = '第'+index+'个设置的标题不能为空';
				break;
			}
			info.value.trim();
			if(info.type == 'radio' || info.type == 'checkbox')
			{
				var ext = info.ext?info.ext:[];
				if(ext.length < 1)
				{
					hasErrorText = '第'+index+'个设置最少有一个选项';
					break;
				}
				for(var y=0;y<ext.length;y++)
				{
					if(!ext[y] || ext[y] == '')
					{
						hasErrorText = '第'+index+'个设置,选项'+(y+1)+'不能为空';
						break; //跳出ext的循环
					}
					ext[y].trim();
				}
				info.ext = ext;
				if(hasErrorText)
				{
					break; //有错误跳出整个for循环
				}
			}
			data[i] = info;
		}
		if(hasErrorText)
		{
			_this.msg(hasErrorText);
			return [];
		}
		return data;
	},
	//获取md5名称
	getMd5Name(str,getRandomStr=true){
		if(getRandomStr == true)
		{
			str = str + this.getRandomStr(6);
		}
		return md5js.hex_md5(str)
	},
	//获取随机字符串
	getRandomStr(number){
	    var x='AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789';
	    let str = ''
	    for(let i=0;i<number;i++){
	        //重点  这里利用了Math.random()函数生成的随机数大于0 小于1 我们可以
	        //用它的随机数来乘以字符串的长度,得到的也是一个随机值，再通过parseInt()
	        //函数取整，这样就可以实现字符串的随机取值了
	        str +=  x[parseInt(Math.random()*x.length)]
	    }
	    return str
	},
	copyText(text){
		var that = this;
		if(!text || text == '')
		{
			that.msg('未获取到复制内容');return;
		}
		switch(typeof text)
		{
			case 'number':
				text = text.toString();break;
			case 'object':
				text = JSON.stringify(text);break;
		}
		uni.setClipboardData({
			data: text,
			success: function () {
				that.msg('复制成功');
			},
			fail:function(){
				that.msg('复制失败');
			}
		});
	},
	openFile(url){
		var that = this;
		if(!url)
		{
			that.msg('缺少文件地址');return ;
		}
		that.loadingMsg('正在下载文件');
		//console.log(url)
		uni.downloadFile({
			url: url, 
			success: (res) => {
				uni.hideLoading();
				var filePath = res.tempFilePath?res.tempFilePath:'';
				uni.openDocument({
					filePath: filePath,
					showMenu: true,
					success: function (res) {
						console.log(res)
					},
					fail(e){
						that.msg('文件不存在或文件类型不支持');
					}
				});
			},
			fail(e){
				uni.hideLoading();
				that.msg('下载文件失败:'+(e.errMsg?e.errMsg:''));
			}
		});
	},
	joinRuleList(){
		return [
			{id:1,title:'所有人可见'},
			{id:2,title:'仅管理员可见'},
			{id:3,title:'参加者和管理员可见'}
		];
	},
	checkScopeRecord(callback){
		uni.authorize({
			scope: 'scope.record',
			success(e) {
				if(typeof callback == 'function')
				{
					callback(e)
				}
			},
		  fail() {
			uni.showModal({
				title:'请先允许使用麦克风',
				confirmText:'去授权',
				success:function(res){
					if(res.confirm)
					{
						uni.openSetting({})
					}
				},
			})
		  }
		})
	},
	checkPhotoRecord(callback){
		uni.authorize({
			scope: 'scope.writePhotosAlbum',
			success(e) {
				if(typeof callback == 'function')
				{
					callback(e)
				}
			},
		  fail() {
			uni.showModal({
				title:'请先允许保存到相册',
				confirmText:'去授权',
				success:function(res){
					if(res.confirm)
					{
						uni.openSetting({})
					}
				},
			})
		  }
		})
	},
	showImage:function(urlArr){
		uni.previewImage({
			urls: urlArr,
			longPressActions: {
				itemList: [],
				success: function(data) {
					
				},
				fail: function(err) {
					console.log(err.errMsg);
				}
			}
		});
	},
	
	setCachePhoneMobile:function(type,mobile){
		type = type?type:'get';
		mobile = mobile?mobile:'';
		var key = 'api-obj-getPhoneMobile';
		var keytime = 'api-obj-getPhoneMobile-time';
		switch(type)
		{
			case 'set':
				uni.setStorageSync(key,mobile);
				uni.setStorageSync(keytime,this.getTime() + 3600 );
				break;
			case 'get':
				var mobile = uni.getStorageSync(key);
				if(!mobile || mobile == '')
				{
					return '';
				}
				var exp_time = uni.getStorageSync(keytime);
				if(exp_time < this.getTime())
				{
					this.setCachePhoneMobile('del');
					return '';
				}
				return mobile;
				break;
			case 'del':
				uni.removeStorageSync(key);
				uni.removeStorageSync(keytime);
				break
		}
	},
	getPhoneMobile:function(params,callback)
	{
		var that = this;
		var mobile = that.setCachePhoneMobile();
		if(mobile)
		{
			if(typeof callback == 'function')
			{
				callback({
					phone:mobile
				})
			}
			return;
		}
		that.loadingMsg('正在获取');
		http.post('config/getMobile',{
			code:params.code
		}).then(res=>{
			if(res.code == 1 && res.data.phone)
			{
				that.setCachePhoneMobile('set',res.data.phone)
				if(typeof callback == 'function')
				{
					callback({
						phone:res.data.phone
					})
				}
			}else{
				that.msg(res.msg)
			}
		})
		
	},
	getErrorImage(type){
		type = type?type:'image';
		var errorImage = this.getSystemConfig('errorImage');//myconfig.errorImage;
		return errorImage[type]?errorImage[type]:'';
	},
	async checkQiniuText(text='')
	{
		text = text.replace(/\n/g,',');
		text = text.replace(' ','');
		if(!text || text == '')
		{
			return true;
		}
		apiObj.loadingMsg('正在检测内容');
		return new Promise((resolve, reject) =>  {
			//uniapi/qiniunotice/checkText
			http.post('wechat/checkText',{
				text
			}).then(res=>{
				if(res.code == 1){
					resolve({
						status:true
					});
				}else{
					var resData = res.data;
					apiObj.showModal(resData.title,resData.content,'',{
						hideCancel:true
					})
					//apiObj.msg(res.msg);
					resolve({
						status:false
					});
				}
			}).catch(res=>{
				apiObj.msg('检测失败');
				resolve({
					status:false
				});
			})
		})
	},
	getSystemConfig:function(key)
	{
		var config = uni.getStorageSync('common-system-config');
		var keyArr = key?key.split('.'):[];
		switch(keyArr.length)
		{
			case 1:
				var res = config[keyArr[0]]?config[keyArr[0]]:{};
				break;
			case 2:
				var info = config[keyArr[0]]?config[keyArr[0]]:{};
				var res = info[keyArr[1]]?info[keyArr[1]]:{};
				break;
			default:
				var res = config;
				break;
		}
		return res;
	},
	updateVersion ()
	{
		let updateManager = uni.getUpdateManager();
		if (!updateManager) {
			return false;
		} else {
			//新版本更新
			if (uni.canIUse('getUpdateManager')) {
				//判断当前微信版本是否支持版本更新
				updateManager.onCheckForUpdate(function(res) {
					if (res.hasUpdate) {
						// 请求完新版本信息的回调
						updateManager.onUpdateReady(function() {
							uni.showModal({
								title: '更新提示',
								content: '新版本已经准备好，立即重启应用？',
								showCancel:false,
								success: function(res) {
									if (res.confirm) {
										// 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
										updateManager.applyUpdate();
									}
								},
							});
						});
						updateManager.onUpdateFailed(function() {
							uni.showModal({
								// 新的版本下载失败
								title: '已经有新版本了哟~',
								content: '新版本已经上线啦~，请您删除当前小程序，重新搜索打开哟~',
							});
						});
					} else {}
				});
			} else {
				uni.showModal({
					// 如果希望用户在最新版本的客户端上体验您的小程序，可以这样子提示
					title: '提示',
					content: '当前微信版本过低，部分功能无法使用，请升级到最新微信版本后重试。',
				});
			}

		}
	}
};


export {apiObj}